﻿using System;

using System.Data;

using System.Reflection;

using System.Reflection.Emit;

namespace TM.Common.Extensions
{
    /// <summary>
    /// Summary description for Converter.
    /// </summary>
    public static class ObjectConverter
    {

        /// <summary>
        ///
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static void ConvertToDataTable(Object o, ref DataTable dataTable)
        {
            PropertyInfo[] properties = o.GetType().GetProperties();
            dataTable = CreateDataTable(properties);
            FillData(properties, dataTable, o);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static void ConvertToDataTable(Object[] array, ref DataTable dataTable)
        {
            PropertyInfo[] properties = array.GetType().GetElementType().GetProperties();
            dataTable = CreateDataTable(properties);
            if (array.Length != 0)
            {
                foreach (object o in array)
                    FillData(properties, dataTable, o);
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="properties"></param>
        /// <returns></returns>
        private static DataTable CreateDataTable(PropertyInfo[] properties)
        {
            DataTable dt = new DataTable();
            DataColumn dc = null;
            foreach (PropertyInfo pi in properties)
            {
                dc = new DataColumn();
                dc.ColumnName = pi.Name;
                dc.DataType = getColumnDataType(pi);
                dt.Columns.Add(dc);
            }
            return dt;
        }

        private static Type getColumnDataType(PropertyInfo pi)
        {
            if(pi.PropertyType == typeof(DateTime?))
            {
                return typeof(DateTime);
            }
            else if(pi.PropertyType == typeof(decimal?))
            {
                return typeof(decimal);
            }

            return pi.PropertyType;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="properties"></param>
        /// <param name="dt"></param>
        /// <param name="o"></param>
        private static void FillData(PropertyInfo[] properties, DataTable dt, Object o)
        {
            DataRow dr = dt.NewRow();
            foreach (PropertyInfo pi in properties)
                dr[pi.Name] = getValue(pi,o);
            dt.Rows.Add(dr);
        }

        private static object getValue(PropertyInfo pi, Object o)
        {
            if (pi.PropertyType == typeof(DateTime?))
            {
                return pi.GetValue(o, null) == null ? System.DBNull.Value : pi.GetValue(o, null);
            }
            else if (pi.PropertyType == typeof(decimal?))
            {
                return pi.GetValue(o, null) == null ? System.DBNull.Value : pi.GetValue(o, null);
            }

            return pi.GetValue(o, null);
        }
    }
}
